#include <string>
#include <iostream>
#include <sstream>
#include <list>
#include <iterator>
#include <algorithm>

#include "baseCard.h"
#include "baseDeck.h"
#include "baseToken.h"

class baseCard;
class baseToken;

using namespace std;

baseDeck::baseDeck()
{
    cards.clear();
}

baseDeck::baseDeck(list<baseCard*> aCards) : cards(aCards) {}

list<baseCard*> baseDeck::getCards()
{
    return this->cards;
}

int baseDeck::countCards()
{
    return cards.size();
}

string baseDeck::toString()
{
    stringstream out;

    out << "Deck: " << "(" << countCards() << ")" << endl;

    out << cardsListToString();

    return out.str();
}

void baseDeck::toString(ostream &out)
{
    out << toString();
}

void baseDeck::toString(string &str)
{
    str = str + toString();
}

string baseDeck::cardsListToString()
{
    stringstream out;

    list<baseCard*>::iterator lit(cards.begin()), lend(cards.end());
    for(;lit!=lend;++lit) out << (*lit)->toString();
    out << endl;

    return out.str();
}

void baseDeck::addCardTop(baseCard* aCard)
{
    if(cards.size() == 0 || find(cards.begin(), cards.end(), aCard) == cards.end())
        cards.push_front(aCard);
}

void baseDeck::addCardBottom(baseCard* aCard)
{
    cards.push_back(aCard);
}

void baseDeck::removeCard(baseCard* aCard)
{
    cards.remove(aCard);
}

baseCard* baseDeck::draw()
{
    baseCard *res = NULL;

    if(!cards.empty())
    {
        res = cards.front();
        cards.pop_front();
    }

    return res;
}

void baseDeck::trashTop()
{
    if(!cards.empty())
    {
        cards.pop_front();
    }
}

void baseDeck::shuffle()
{
    vector<baseCard*> tempVect(cards.begin(), cards.end());
    random_shuffle(tempVect.begin(), tempVect.end());
    cards.clear();
    copy( tempVect.begin(), tempVect.end(), back_inserter( cards ) );
}

bool baseDeck::empty()
{
    return (countCards() == 0);
}
